home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Science⁄Math / VideoToolbox / VideoToolboxSources / Luminance.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-29  |  11.2 KB  |  244 lines  |  [TEXT/KAHL]

  1. /*
  2. Luminance.h
  3. This is the include file for Luminance.c and ReadLuminanceRecord.c
  4. Copyright 1989,1990,1991,1992 (c) Denis G. Pelli 
  5. HISTORY:
  6. 9/18/90    dgp    Changed all instances of "v" to "V". The final version of the Pelli
  7.             & Zhang (1991) manuscript refers to a nominal voltage v; this file
  8.             now refers to the "equivalent number" V; they are related by V=255*v.
  9.             To avoid "breaking" all the old LuminanceRecord.h files, I've 
  10.             introduced a #define that converts vMin & vMax to VMin & VMax. However,
  11.             this is a temporary fix. I'll probably remove the define in a few months,
  12.             so you should still update any old calibration files, either by editing,
  13.             replacing "vM" by "VM" or by redoing the calibration.
  14. 9/24/90    dgp    Added screen & date. Renamed nBackground to VBackground.
  15.             Renamed index to lastIndex.
  16. 9/28/90    dgp    Renamed lastIndex to latestIndex. Spruced up some of the comments.
  17. 10/31/90 dgp Added the conditional FAST_LUMINANCE. Setting it to 1 (true) makes
  18.             SetLuminancesAndRange() run twice as fast, by using fixed point
  19.             arithmetic instead of doubles. Setting it to 0 (false) causes the
  20.             same code to be compiled to use doubles. Note that the prototypes of
  21.             some internal functions (names beginning with underscore) are conditional
  22.             on FAST_LUMINANCE.
  23. 11/6/90 dgp Replaced Milli by Fixed. 
  24. 11/8/90 dgp    Eliminated gamma slope table shiftedLSlope[] since the speed-up it offered
  25.             was too small to measure.
  26. 7/30/91    dgp    Added prototype for ReadLuminanceRecord().
  27. 8/4/91    dgp    Change ReadLuminanceRecord() to return type int.
  28. 8/5/91    dgp    Trying to compile under MPW C 3.2 uncovered a name-space conflict.
  29.             The MPW C 3.2 CType.h header file defines _L as a preprocessor constant,
  30.             whereas Luminance.h uses it as a field of the luminanceTable structure,
  31.             and as a parameter name.
  32.             The THINK C 4.05 ctype.h header file names the same constant __LOWR,
  33.             which of course doesn't conflict. The obvious solution would be to
  34.             change MPW's CType.h _L to _LOWR, but that would compromise portability.
  35.             I decided not to change _L in Luminance.h and Luminance.c,
  36.             because it would be hard to do that in a way that wouldn't compromise 
  37.             the readability of the code. However, I did do a quick hack, 
  38.             about ten lines below, that redefines _L as an enum, which solves the
  39.             problem, provided CType.h is included before Luminance.h in files that
  40.             need to explicitly access _L. In fact _L is intended for use
  41.             only by the routines that are in Luminance.c, so I suspect the
  42.             problem is solved.
  43. 12/17/92    dgp Removed obsolete support for THINK C 4. 
  44. 12/21/92 dgp Added dacSize and leftShift.
  45. 6/5/93    dgp    Removed the ancient #defines that were required to read ≤1990 calibration
  46.             files.
  47. 8/12/93    dgp    updated ReadLuminanceRecord() prototype to match source file.
  48. */
  49.  
  50. #pragma once        /* suppress multiple inclusions of this file */
  51. #ifndef _LUMINANCE_    /* suppress multiple inclusions of this file */
  52. #define _LUMINANCE_
  53.  
  54. #ifndef __QUICKDRAW__
  55.     #include <QuickDraw.h>
  56. #endif
  57. #ifndef __SOUND__
  58.     #include <Sound.h>
  59. #endif
  60. /*
  61. The following trickery redefines the MPW C 3.2 CType.h define constant
  62. _L as an enum, so that it won't conflict with the use of _L as a parameter name or
  63. structure field.
  64. */
  65. #ifdef _L
  66.     enum{____L=_L};
  67.     #undef _L
  68.     enum{_L=____L};
  69. #endif
  70.  
  71. /* These 3 #defines are a temporary fix, to allow use of old LuminanceRecord.h files */
  72. #if 0
  73.     #define vMin VMin
  74.     #define vMax VMax
  75.     #define nBackground VBackground
  76. #endif
  77.  
  78. /* LINEAR_V_DOMAIN is the maximum interval in V over which the gamma function is
  79. to be assumed linear by LToV(). The value 4 gives almost the same accuracy as 1, yet
  80. results in SetLuminances() on a Mac II taking only 29 ms instead of 50 ms. 
  81. See _LToV() in Luminance.c  for more information. */
  82.  
  83. #define MACINTOSH    1        /* set to 0 to use on any other computer */
  84. #define LINEAR_V_DOMAIN 4    /* see above */
  85. #define FAST_LUMINANCE 1    /* 1 for Fixed math (twice as fast), 0 for double math */
  86. #define DACS 3                /* number of digital-to-analog converters that we support */
  87. #define COLORS 256            /* size of ColorSpec table */
  88. #define MAX_COEFFICIENTS 9    /* polynomial fit */
  89. #define LUMINANCES_IN_TABLE 128    /* size of gamma table */
  90.  
  91. #if FAST_LUMINANCE & !defined(__TOOLUTILS__)
  92.     #include <ToolUtils.h>    /* prototypes for FixMul etc. */
  93. #endif
  94.  
  95. typedef struct{
  96.     ColorSpec table[COLORS];    /* a table of values destined for the clut */
  97. } Clut;
  98.  
  99. enum {Michelson,Weber};    /* contrastType */
  100.  
  101. typedef struct {
  102.     short exists;    /* set to luminanceSet once this table has been initialized */
  103.     short latestIndex;/* last-used index of LR.L._L[] is good place to start search */
  104.     #if FAST_LUMINANCE
  105.         Fixed _VMin;    /* bounds monotonic part of domain of gamma function */
  106.         Fixed _VMax;    /* bounds monotonic part of domain of gamma function */
  107.         Fixed _dV;        /* V = _VMin,_VMin+_dV,_VMin+2dV,_VMin+3dV, . . . ,_VMax */
  108.                         /* _dV=(_VMax-_VMin)/(LUMINANCES_IN_TABLE-1) */
  109.         Fixed _L[LUMINANCES_IN_TABLE];
  110.         long LShift;    /* bit shift to be applied to luminance differences */
  111.     #else
  112.         double _VMin;    /* bounds monotonic part of domain of gamma function */
  113.         double _VMax;    /* bounds monotonic part of domain of gamma function */
  114.         double _dV;        /* V = _VMin,_VMin+_dV,_VMin+2dV,_VMin+3dV, . . . ,_VMax */
  115.                         /* _dV=(_VMax-_VMin)/(LUMINANCES_IN_TABLE-1) */
  116.         double _L[LUMINANCES_IN_TABLE];
  117.     #endif
  118. } luminanceTable;
  119.  
  120. typedef struct {    /* "table" MUST be the first thing in the structure! */
  121.     ColorSpec table[COLORS];/* a table of values destined for the clut */
  122.     short dacSize;        /* bits */
  123.     short leftShift;    /* bit shift of V to produce 16 bit value=16-dacSize */
  124.     short VMin,VMax;    /* lowest and highest DAC values allowed: 0 and 255 */
  125.     double LMin,LMax;    /* luminances at VMin & VMax */
  126.     double LBackground;    /* the background luminance used during luminance calibration */
  127.     short VBackground;    /* the background number used during luminance calibration */
  128.     short screen;        /* device=GetScreenDevice(LR.screen); */
  129.     char *id;            /* make, model, and serial number of monitor */
  130.     char *name;            /* informal name of monitor */
  131.     char *date;            /* when calibrated */
  132.     char *notes;        /* description of calib conditions: who & how */
  133.     double dpi;            /* pixels per inch */
  134.     double Hz;            /* frames per second */
  135.     char *units;        /* Luminance units, e.g. "cd/m^2" */
  136.     long coefficients;    /* the number of coefficients, not more than MAX_COEFFICIENTS, */
  137.                         /*    usually 9, giving an 8th-order polynomial, */
  138.     double p[MAX_COEFFICIENTS];
  139.                         /* coefficients of a polynomial in value V, yielding L in cd/m^2 */
  140.     double polynomialError;    /* RMS error of polynomial fit */
  141.                         /* L(V)=p[0]+p[1]*V+p[2]*V*V+ . . . ±polynomialError */
  142.     double q[3];        /* coefficients of a quadratic polynomial in V */
  143.     double quadraticError;    /* RMS error of quadratic fit */
  144.                         /* L(V)=q[0]+q[1]*V+q[2]*V*V±quadraticError */
  145.     double power[4];    /* coefficients of a power law fit */
  146.     double powerError;    /* RMS error of power law fit */
  147.                         /* L(V)=power[0]+Rectify(power[1]+power[2]*V)^power[3]±powerError */
  148.                         /* Rectify(x)=x if x≥0, Rectify(x)=0 if x<0 */
  149.                         /* Pelli & Zhang (1991) Eqs.9&10 use symbols: */
  150.                         /* v=V/255, alpha=power[0], beta=power[1], kappa=power[2]*255, */
  151.                         /* gamma=power[3] */
  152.     double fixedPower[4];    /* coefficients of a power law fit, with fixed exponent */
  153.     double fixedPowerError;    /* RMS error of power law fit */
  154.                         /* L(V)=fixedPower[0]+Rectify(fixedPower[1]+fixedPower[2]*V)^fixedPower[3]±fixedPowerError */
  155.     double r,g,b;        /* voltage gains for the three pathways. r+g+b=1. All must be ≥0. */
  156.     double gainAccuracy;/* possible error in r,g,b */
  157.     double gm;            /* The monitor's contrast gain. The Michelson contrast produced by
  158.                             a small Δv at the background luminance is c=gm*Δv */
  159.     /* The rest of the parameters are for temporary storage by SetLuminanceRange() */
  160.     double lowLuminance;    /* the bottom of the range */
  161.     double highLuminance;    /* the top of the range */
  162.     short rangeSet;            /* a check that the range really has been set */
  163.     short dacs;                /* the number of dacs with nonzero gain, usually 1 or 3 */
  164.     short fixed;            /* the number of dacs whose value will be fixed for this range */
  165.     short dac[DACS];        /* which dac corresponds to each gain, r=0,g=1,b=2 */
  166.     double gain[DACS];        /* the ordered normalized gains of the Video Attenuator */
  167.     double VHalfStep;        /* half a step of the finest dac */
  168.     double VFixed;            /* the value produced by the fixed dacs */
  169.     double LOffset;            /* a small shift of the requested luminance range */
  170.     double tolerance;        /* the luminance error corresponding to half 
  171.                                 a step of the coarsest of the variable dacs */
  172.     #if FAST_LUMINANCE
  173.         Fixed _gain[DACS];
  174.         Fixed _VHalfStep;
  175.         Fixed _VFixed;
  176.         Fixed _LOffset;
  177.         Fixed _tolerance;
  178.     #else
  179.         double _gain[DACS];
  180.         double _VHalfStep;
  181.         double _VFixed;
  182.         double _LOffset;
  183.         double _tolerance;
  184.     #endif
  185.     RGBColor rgb;            /* cache the values of the fixed DACs */
  186.     luminanceTable L;
  187. } luminanceRecord;
  188.  
  189. enum {luminanceSet=12345};    /* a unique value that we can check for later */
  190.  
  191. /* Luminance.c */
  192. double SetLuminance(GDHandle device,luminanceRecord *LP
  193.     ,int theEntry,double luminance
  194.     ,double lowLuminance,double highLuminance);
  195. double SetLuminances(GDHandle device,luminanceRecord *LP
  196.     ,int firstEntry,int lastEntry
  197.     ,double firstLuminance,double lastLuminance);
  198. double SetLuminancesAndRange(GDHandle device,luminanceRecord *LP
  199.     ,int firstEntry,int lastEntry
  200.     ,double firstLuminance,double lastLuminance
  201.     ,double lowLuminance,double highLuminance);
  202. void LoadLuminances(GDHandle device, luminanceRecord *LP,
  203.     int firstEntry, int lastEntry);
  204. void IncrementLuminance(GDHandle device,luminanceRecord *LP,int theEntry);
  205. double GetLuminance(GDHandle device,luminanceRecord *LP,int theEntry);
  206. double GetV(GDHandle device,luminanceRecord *LP,int theEntry);
  207. double VToL(luminanceRecord *LP,double V);
  208. double LToV(luminanceRecord *LP,double L);
  209. double LToVFormulaic(luminanceRecord *LP,double L);
  210. double LToL(luminanceRecord *LP,double L);
  211.  
  212. /* The following routines are primarily for internal use. */
  213. #if FAST_LUMINANCE
  214.     void _SetLuminance(luminanceRecord *LPtr,int theEntry,Fixed _luminance);
  215.     Fixed _Tolerance(luminanceRecord *LP,Fixed _luminance);
  216.     void _SetLuminances(luminanceRecord *LP,int first,int last
  217.         ,Fixed _firstL,Fixed _dL64,Fixed _firstV,Fixed _lastV);
  218.     Fixed _VToL(luminanceRecord *LP,Fixed _V);
  219.     Fixed _LToV(luminanceRecord *LP,Fixed _L);
  220. #else
  221.     void _SetLuminance(luminanceRecord *LPtr,int theEntry,double _luminance);
  222.     double _Tolerance(luminanceRecord *LP,double _luminance);
  223.     void _SetLuminances(luminanceRecord *LP,int first,int last
  224.         ,double _firstL,double _dL8,double _firstV,double _lastV);
  225.     double _VToL(luminanceRecord *LP,double _V);
  226.     double _LToV(luminanceRecord *LP,double _L);
  227. #endif
  228. double SetLuminanceRange(luminanceRecord *LP
  229.     ,double lowLuminance,double highLuminance);
  230. double VToLPower(luminanceRecord *LP,double V);            /* use VToL() instead */
  231. double VToLPolynomial(luminanceRecord *LP,double V);    /* use VToL() instead */
  232. double LToVPower(luminanceRecord *LP,double L);            /* use LToV() instead */
  233. double LToVPolynomial(luminanceRecord *LP,double L);    /* use LToV() instead */
  234. double LToVQuadratic(luminanceRecord *LP,double L);        /* use LToV() instead */
  235.  
  236. /* ReadLuminanceRecord.c */
  237.  
  238. long ReadLuminanceRecord(char *filename,luminanceRecord *LP,short flags);
  239. long WriteLuminanceRecord(char *filename,luminanceRecord *LP,short flags);
  240. Description *DescribeLuminanceRecord(luminanceRecord *LP);
  241.  
  242. #endif _LUMINANCE_
  243.  
  244.